package meterMonitor.biz;

import meterMonitor.dto.QueryByIdsDto;
import meterMonitor.dto.mqttApi.KeyAndNameDto;
import meterMonitor.dto.mqttApi.KeyAndNameResponse;
import meterMonitor.mapper.*;
import meterMonitor.model.*;
import meterMonitor.util.*;
import meterMonitor.vo.MeterInfoShort;
import meterMonitor.vo.MeterUpdatesVO;
import meterMonitor.vo.QueryForChartRequest;
import meterMonitor.vo.SetIntervalTimeVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

//import java.text.SimpleDateFormat;

/**
 * Created by admin on 2019/1/3.
 */
@Service
public class MeterBiz extends BaseBiz {

    /**
     * 使用指定类初始化日志对象
     *
     * 在日志输出的时候，可以打印出日志信息所在类
     * 如：Logger logger = LoggerFactory.getLogger(com.Book.class);
     *        logger.debug("日志信息");
     *        将会打印出: com.Book : 日志信息
     */
    public static final Logger logger = LoggerFactory.getLogger(MeterBiz.class);
    @Autowired
    protected ResourceConfig resourceConfig;

    @Autowired
    protected MeterMapper meterMapper;

    @Autowired
    private MqttApiUtil mqttApiUtil;

    @Autowired
    private HistoryMapper historyMapper;

    //区域
    @Autowired
    private AreaMapper areaMapper;

    //监控
    @Autowired
    private MonitorMapper monitorMapper;

    //读表器
    @Autowired
    private ReaderMapper readerMapper;

    //根据读表器编码查询读表器
    public Reader queryReaderByReaderCode(String readerCode) {
        return readerMapper.queryByReaderCode(readerCode);
    }

    //添加仪器设备
    public void insert(Meter meter) throws Exception {
        /**添加时间
         * System.currentTimeMillis()获取的是当前的系统时间，不是网络时间
         * Timestamp对日期进行类型转换
         */
        meter.setAddedTime(new Timestamp(System.currentTimeMillis()));
        // 校验仪器编码
        //根据仪表识别码查出meter
        Meter existsMeter = meterMapper.queryByReaderCode(meter.getReaderCode());
        //根据设备名称查出meter
        //Meter existsMeter2 = meterMapper.queryByDeviceName(meter.getDeviceName());
        //进行非空判断，若existsMeter为空，且existsMeter2也为空
        if (Objects.isNull(existsMeter)) {
            //将meter的状态吗码设置为10（启用状态）
            meter.setStatus(10);
            //添加meter
            meterMapper.add(meter);
        } else {
            //如果existsMeter不为空
            if (Objects.nonNull(existsMeter))
                //抛出传感器某某已被占用异常
                throw new Exception("仪器识别码：" + meter.getReaderCode() + "已被占用！");
            //如果existsMeter2不为空
        }
    }


    //修改仪器设备
    public void update(Meter meter) throws Exception {
        Meter existsMeter = meterMapper.queryByReaderCode(meter.getReaderCode());
        Meter existsMeter2 = meterMapper.queryByDeviceName(meter.getDeviceName());
        if ((Objects.isNull(existsMeter) || existsMeter.getMeterCode().equals(meter.getMeterCode())) && (Objects.isNull(existsMeter2) || existsMeter2.getMeterCode().equals(meter.getMeterCode()))) {
            meter.setLastModifyTime(new Timestamp(System.currentTimeMillis()));
            meterMapper.update(meter);
        } else {
            if (Objects.nonNull(existsMeter) && !existsMeter.getMeterCode().equals(meter.getMeterCode()))
                throw new Exception("传感器：" + meter.getReaderCode() + "已被占用！");
            if (Objects.nonNull(existsMeter2) && !existsMeter2.getMeterCode().equals(meter.getMeterCode()))
                throw new Exception("设备编号：" + meter.getDeviceName() + "已被占用！");
        }
    }

    public void deleteMeterById(long meterCode) {
        meterMapper.deleteByPrimaryKey(meterCode);
    }

    //查出符合条件的水表

    public List<Meter> queryMeter(Meter condition) {
        return meterMapper.queryMeter(condition);
    }

    //yy:根据设备类型查出所有设备
    public List<Meter> queryMeterByDevice(int deviceTypeCode){
        return meterMapper.queryMeterByDevice(deviceTypeCode);
    }

    public List<Meter> queryMeterWater(Meter condition) {
        return meterMapper.queryMeterWater(condition);
    }
    //查出符合条件的水表test
    public List<Meter> queryMeterWithType(Meter condition) {
        return meterMapper.queryMeter(condition);
    }


    //查出符合条件的电表
    public List<Meter> queryElectricityMeter(Meter condition){
        return meterMapper.queryElectricityMeter(condition);
    }

    //查出离线仪器的时间
    public List<Meter> queryTimeByOffline(Long meterCode){
        return meterMapper.queryTimeByOffline(meterCode);
    }
    //查出超标仪器的时间
    public List<Meter> queryTimeByExcessive(Long meterCode){
        return meterMapper.queryTimeByExcessive(meterCode);
    }

    //查询全部在线水电表
    public List<Meter> queryAllMeter() {
        return meterMapper.queryAllMeter();
    }

    //查询全部水表
    public List<Meter> queryAllMeter1() {
        return meterMapper.queryAllMeter1();
    }

    //有用：查询全部水电表
    public List<Meter> queryAllMeterNoStatus(int deviceTypeCode){
        return meterMapper.queryAllMeterNoStatus(deviceTypeCode);
    }




    //查询全部在线电表
    public List<Meter> queryAllMeterElectricity(){
        return meterMapper.queryAllMeterElectricity();
    }


    //修改或者保存Meter
    public void saveOrUpdateMeter(List<Meter> list) {

        //修改
        if (list.get(0).getMeterCode() != null) {
            for (Meter meter : list) {
                meter.setLastModifyTime(new Timestamp(System.currentTimeMillis()));
                meterMapper.updateByPrimaryKey(meter);
            }


            //保存
        } else {
            list.get(0).setLastModifyTime(new Timestamp(System.currentTimeMillis()));
            meterMapper.add(list.get(0));
        }

    }

    //编辑所有Meter
    public void updateAll(MeterUpdatesVO meterUpdatesVO) {
        meterMapper.updateAll(meterUpdatesVO);
    }

    //单个或者批量删除Meter
    public void deleteMeters(List<Meter> list) {
        for (Meter meter : list) {
            meterMapper.deleteByPrimaryKey(meter.getMeterCode());
        }
    }


    //查询全部区域
    public List<Area> queryAllArea() {
        return areaMapper.getAllAreas();
    }

    //删除Meter
    public void deleteMeter(Meter meter) {
        meterMapper.deleteByPrimaryKey(meter.getMeterCode());
    }

    //根据ID查Meter
    public Meter selectByPrimaryKey(Long pkid) {
        return meterMapper.selectByPrimaryKey(pkid);
    }

    //查询标准值
    public double queryStandard(QueryForChartRequest reqDto) {
        if (reqDto.getAnotherName() != null) {
            boolean isAll = false;
            for (String no : reqDto.getAnotherName()) {
                if (no.equals("-1")) {
                    isAll = true;
                    break;
                }
            }
            if (isAll) {
                reqDto.setAnotherName(null);
            }
        }
        Meter meter = this.meterMapper.queryStandardForCharts(reqDto);
        if (meter == null) {
            return 0;
        }
        boolean isSameDay = reqDto.getEndDate().equals(reqDto.getStartDate());

        if (reqDto.getType() == 10) {//白班
            //同一天按小时统计
            if (isSameDay) {
                return meter.getStandardDay() / 12;
            }
            return meter.getStandardDay();
        } else if (reqDto.getType() == 20) {//夜班
            //同一天按小时统计
            if (isSameDay) {
                return meter.getStandardNight() / 12;
            }
            return meter.getStandardNight();
        } else if (reqDto.getType() == 30) {//日报
            //同一天按小时统计
            if (isSameDay) {
                return (meter.getStandardNight() + meter.getStandardDay()) / 24;
            }
            return meter.getStandardNight() + meter.getStandardDay();
        } else {
            Date date = DateUtils.parse(reqDto.getStartDate(), DateUtils.PATTERN_CLASSICAL_SIMPLE);
            int monsDays = DateUtils.getDayOfMonth(date);
            //double保留2位小数四舍五入
            DecimalFormat df = new DecimalFormat("#0.00");
            double standard = monsDays * (meter.getStandardNight() + meter.getStandardDay());
            standard = Double.valueOf(df.format(standard));
            return standard;
        }
    }

    /**
     * 设置设备频率
     *
     * @param vo
     */
    public void setIntervalTime(SetIntervalTimeVo vo) {
        QueryByIdsDto dto = new QueryByIdsDto();
        if (!vo.getPkids().equals("-1")) {
            List<Long> ids = new ArrayList<Long>();
            String[] arr = vo.getPkids().split(",");
            for (String str : arr) {
                ids.add(Long.parseLong(str));
            }
            dto.setPkids(ids);
        }
        String sendTime = vo.getSendTime();
        String hour = sendTime.substring(0, 2);
        String min = sendTime.substring(3, 5);

        List<Meter> meters = meterMapper.queryMeterByIds(dto);
        if (meters == null || meters.size() == 0) {
            throw new BizException("没有找到设备，请检查！");
        }
        String token = mqttApiUtil.getToken();
        if (StringUtils.isBlank(token)) {
            throw new BizException("未获取到mqtt厂商授权，请联系管理员");
        }
        Meter saveMeter;
        for (Meter meter : meters) {
            // meter.setIntervalTime(vo.getIntervalTime());
            //meter.getSendTime(vo.getSendTime());
            // meter.setSendTime(vo.getSendTime());
            boolean flag = this.setIntervalTimeRemote(meter, token);
            if (flag) {
                saveMeter = new Meter();
                saveMeter.setMeterCode(meter.getMeterCode());
                //saveMeter.setIntervalTime(meter.getIntervalTime());
                // saveMeter.setSendTime(meter.getSendTime());
                saveMeter.setStandardDay(meter.getStandardDay());
                saveMeter.setStandardNight(meter.getStandardNight());
                saveMeter.setLastModifyTime(new Timestamp(System.currentTimeMillis()));
                meterMapper.updateByPrimaryKeySelective(saveMeter);
            }
        }
    }

    public void getConfigAndUpdate() {
        QueryByIdsDto dto = new QueryByIdsDto();
        List<Meter> meters = meterMapper.queryMeterByIds(dto);
        if (meters == null || meters.size() == 0) {
            throw new BizException("没有找到设备，请检查！");
        }
        String token = mqttApiUtil.getToken();
        if (StringUtils.isBlank(token)) {
            throw new BizException("未获取到mqtt厂商授权，请联系管理员");
        }
        Meter saveMeter;
        String str = "";
        for (Meter meter : meters) {
            KeyAndNameResponse existConfig = mqttApiUtil.getWakeConfig(meter, token);
            if (existConfig == null || existConfig.getData() == null || existConfig.getCode() != 200) {
                logger.warn("设备" + meter.getDeviceName() + "未获取到配置，无法更新频率");
                continue;
            }
            str += "\r\n厂商设备配置：" + JacksonMapper.toJson(existConfig);
            saveMeter = new Meter();
            saveMeter.setMeterCode(meter.getMeterCode());
            // saveMeter.setIntervalTime(existConfig.getData().getInterval().intValue());
            saveMeter.setLastModifyTime(new Timestamp(System.currentTimeMillis()));
            meterMapper.updateByPrimaryKeySelective(saveMeter);
        }
        logger.info(str);
    }

    //调用供应商rest服务接口，设置数据频率
    private boolean setIntervalTimeRemote(Meter meter, String token) {
        KeyAndNameResponse existConfig = mqttApiUtil.getWakeConfig(meter, token);
        if (existConfig == null || existConfig.getData() == null || existConfig.getCode() != 200) {
            logger.warn("设备" + meter.getDeviceName() + "未获取到配置，无法更新频率");
            return false;
        }
        KeyAndNameDto updateDto = existConfig.getData();
        //updateDto.setInterval(meter.getIntervalTime().longValue());
        // String sendTime = meter.getSendTime();
        // String hour = sendTime.substring(0, 2);
        // String min = sendTime.substring(3, 5);
        // updateDto.setHour(Long.valueOf(hour));
        // updateDto.setMinute(Long.valueOf(min));
        boolean flag = mqttApiUtil.setIntervalTime(token, updateDto);
        return flag;
    }

    //更换设备
    public void fixMeter(Meter meter) {
        // double保留3位小数四舍五入
        // DecimalFormat df = new DecimalFormat("#0.000");
        meter.setLastModifyTime(new Timestamp(System.currentTimeMillis()));
        // meter.setStatus(20);
        meterMapper.updateByAnotherNameSelective(meter);
        // meter.setAddedTime(new Date());
        // meter.setStatus(10);
        // meterMapper.updateByDeviceNameSelective(meter);
    }

    //添加到历史信息记录
    public void insertHistory(String meterCode, String dateTime) {
        Map<String, String> map = setTime(dateTime);
        map.put("meterCode", meterCode);
        List<Monitor> list = monitorMapper.selectMonitor(map);
        if (list != null) {
            for (Monitor mod : list) {
                if ("N/A".equals(mod.getIsNA())) {
                    mod.setIsNA("ok");
                    monitorMapper.updateByPrimaryKeySelective(mod);
                }
            }
        }
////////////////////////////////////////////上面消除"N/A"，下面添加更换记录
        History history = new History();
        history.setMeterCode(meterCode);
        history.setChangDateTime(dateTime);
        historyMapper.insertSelective(history);

    }

    private Map<String, String> setTime(String dateTime) {
        Map<String, String> map = new HashMap<>();
        String hours = dateTime.substring(11, 13);
        String start = "";
        String end = "";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (Integer.valueOf(hours) > 7) {
            try {
                Date endD = sdf.parse(dateTime);
                Date startD = DateUtils.rollDay(endD, -1);

                start = DateUtils.format(startD, "yyyy-MM-dd") + " 07:30:00";
                end = DateUtils.format(endD, "yyyy-MM-dd") + " 07:30:00";

            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {

            Date endD = null;
            try {
                endD = sdf.parse(dateTime);
                Date startD = DateUtils.rollDay(endD, -2);
                endD = DateUtils.rollDay(endD, -1);
                start = DateUtils.format(startD, "yyyy-MM-dd") + " 07:30:00";
                end = DateUtils.format(endD, "yyyy-MM-dd") + " 07:30:00";
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }

        map.put("start", start);
        map.put("end", end);
        return map;
    }

    //查询新增设备设备编号
    public List<String> queryDeviceName() {
        /*
        String param = "init";
        Meter meter = new Meter();
        meter.setAnotherName(param);
        List<String> list = meterMapper.selectDeviceNames(meter);
        return list;
        */
        return meterMapper.selectUnUsedReaders();
    }

    //根据芯片编号查水表位置
    public List<String> getAnotherNameByDeviceName(String deviceName) {

        return meterMapper.getAnotherNameByDeviceName(deviceName);
    }

    public Map<String, Map<String, MeterInfoShort>> mapAreaMeterInfoShort() {
        Map<String, Map<String, MeterInfoShort>> map = new HashMap<String, Map<String, MeterInfoShort>>();
        List<MeterInfoShort> list = meterMapper.queryMetersInfoShort();
        for (MeterInfoShort meterInfoShort : list) {
            Map<String, MeterInfoShort> mmp = map.get(meterInfoShort.getAreaId());
            if (mmp == null) {
                mmp = new HashMap<String, MeterInfoShort>();
                map.put(meterInfoShort.getAreaId(), mmp);
            }
            if (!mmp.containsKey(meterInfoShort.getDeviceName())) {
                mmp.put(meterInfoShort.getDeviceName(), meterInfoShort);
            }
        }
        return map;
    }

    public List<Area> getAllAreas() {
        return areaMapper.getAllAreas();
    }

    public List<MeterInfoShort> queryMetersInfoByArea(Integer areaId) {
        return meterMapper.queryMetersInfoByArea(areaId);
    }
}
